package test.study.concurrent.thread._6_lock;

import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.openjdk.jol.info.ClassLayout;

/**
 * 直接设置为重量级锁
 * -XX:+UseHeavyMonitors
 */
@Slf4j
public class Lock_02_Main {

    public static void main(String[] args) {
        //初始化一个对象，默认是无锁状态（non-biasable）
        Integer initNum = new Integer("1");
        log.info("【non-biasable】 {}", ClassLayout.parseInstance(initNum).toPrintable());

        ThreadUtil.sleep(5000);

        //VM默认启动后等待3s后就会把对象标记为偏向锁（biasable）
        Object lock = new Object();
        log.info(">>>>>> 【biasable】 {}", ClassLayout.parseInstance(lock).toPrintable());

        //添加同步源于可以看到对象被标记为偏向锁（biased）
        synchronized (lock) {
            log.info(">>>>>> 【biased】 {}", ClassLayout.parseInstance(lock).toPrintable());
        }

        //启动一个线程，线程的并发特性（主线程和新起线程并发，同步锁stepNum），导致锁升为轻量级锁（thin lock）
        new Thread(() -> {
            synchronized (lock) {
                log.info(">>>>>> 【thin lock】 {}", ClassLayout.parseInstance(lock).toPrintable());
                //注意这个线程保持锁至少5s，导致下面又新起的线程同步锁stepNum，再次锁升级，由轻量级锁thin变为重量级fat
                ThreadUtil.sleep(5 * 1000);
            }
        }).start();

        ThreadUtil.sleep(1 * 1000);

        //注意这个线程同步锁stepNum，导致锁升级，由轻量级锁thin变为重量级fat，此时打印结果后两位是10。
        new Thread(() -> {
            synchronized (lock) {
                log.info(">>>>>> 【fat lock】 {}", ClassLayout.parseInstance(lock).toPrintable());
            }
        }).start();
    }
}
